package com.example.rabbitmqdemo.mq;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import java.io.IOException;
import java.util.Objects;

/**
 * @author liujb
 * @description TODO 消息生产者
 * @date 2022-06-28 19:03
 */
public class Provider {


    public static void main(String[] args) {

        // 第一种队列模型
//        helloWorld();
        // 第二种队列模型
        workQueues();
        // 发布者/订阅者 - Fanout
//        pubAndSubFanout();
        // 发布者/订阅者 - Direct
//        pubAndSubDirect();
        // 发布者/订阅者 - Topic
//        pubAndSubTopic();

    }

    private static void pubAndSubTopic() {

        Connection connection = null;
        Channel channel = null;
        try{
            // 获取连接
            connection = RabbitmqUtils.getConnection();

            if (Objects.nonNull(connection)) {
                // 获取通道
                channel = connection.createChannel();
                // 声明交换机和交换机类型
                channel.exchangeDeclare("topics", BuiltinExchangeType.TOPIC);
//                String routingKey = "user.save";
                String routingKey = "user";
                String message = "hello topic, routingKey:" + routingKey;
                // 发布消息
                channel.basicPublish("topics", routingKey, null, message.getBytes());
            }

        }catch (IOException e){
            e.printStackTrace();
        }finally {
            // 释放资源
            RabbitmqUtils.close(channel, connection);
        }

    }

    private static void pubAndSubDirect() {
        Channel channel = null;
        // 获取连接对象
        Connection connection = RabbitmqUtils.getConnection();
        try{
            if (Objects.nonNull(connection)) {
                // 获取通道
                channel = connection.createChannel();

                String exchangeName = "test_direct_exchange";
                // 声明交换机
                channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT);
                String message = "this is warning log";
                // 发布消息并指定交换机
                channel.basicPublish(exchangeName, "warning", null, message.getBytes());
                message = "this is info log";
                channel.basicPublish(exchangeName, "info", null, message.getBytes());
                message = "this is error log";
                channel.basicPublish(exchangeName, "error", null, message.getBytes());

            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            // 释放资源
            RabbitmqUtils.close(channel, connection);
        }
    }


    private static void pubAndSubFanout() {

        Channel channel = null;
        // 获取连接对象
        Connection connection = RabbitmqUtils.getConnection();

        try {
            if (Objects.nonNull(connection)) {
                // 获取通道对象
                channel = connection.createChannel();
                // 声明通道指定交换机：
                //  var1：交换机名称
                //  var2：交换机类型
                channel.exchangeDeclare("logs", "fanout");

                // 消息内容
                String message = "fanout message";
                // 发送消息并指定交换机
                channel.basicPublish("logs", "", null, message.getBytes());

            }
        } catch (IOException e){
            e.printStackTrace();
        }finally {
            // 释放资源
            RabbitmqUtils.close(channel, connection);
        }
    }

    // 第二种：队列模型
    private static void workQueues() {
        Connection connection = null;
        Channel channel = null;
        try{
            // 获取连接对象
            connection = RabbitmqUtils.getConnection();
            if (Objects.nonNull(connection)) {
                // 获取通道对象
                channel =  connection.createChannel();
                String queue = "work";
                // 声明队列
                channel.queueDeclare(queue, true, false, false, null);
                // 生产消息
                String message = "";
                for (int i = 0; i < 20; i++) {
                    message = "work queues,id:" + i;
                    channel.basicPublish("", queue, null, message.getBytes());
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            RabbitmqUtils.close(channel, connection);
        }
    }

    /* 第一种：Hello World! */
    private static void helloWorld(){
        Connection connection = null;
        Channel channel = null;
        try {
            // 获取连接对象
            connection = RabbitmqUtils.getConnection();
            // 获取通道
            if (Objects.nonNull(connection)) {
                channel = connection.createChannel();
                String queue = "hello";
                /*
                    通道绑定对应的消息队列
                      参数1 queue：队列名称(不存在自动创建)
                      参数2 durable：用来定义队列特性是否需要持久化(为true该队列将在服务器重启后保留下来，持久化到硬盘中)
                      参数3 exclusive：是否独占队列(为true仅限此连接)
                      参数4 autoDelete：是否在消费完成后自动删除队列
                      参数5 arguments：队列的其他属性（构造参数）
                 */
                channel.queueDeclare(queue, false, false, false, null);
                /*
                    发布消息
                        参数1 exchange：要将消息发布到的交换机
                        参数2 routingKey：路由键，指定队列
                        参数3 props：消息的其他属性
                        参数4 body：消息具体内容
                 */
                String message = "hello rabbitmq";
                channel.basicPublish("", queue, null, message.getBytes());
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("生产者发布消息完成......");
            RabbitmqUtils.close(channel, connection);
        }
    }
}
